﻿/*
 * zip.cxx
 *
 *  Created on: 2015年4月3日
 *      Author: Fifi Lyu
 */

#include "zpsoe/zalgorithm/zip.h"
#ifdef PLATFORM_WIN32
    #if (_WIN32_WINNT >= 0x0600)  // 0x0600 = Vista
        #include <Ws2tcpip.h>  // for InetPton
        #include <Inaddr.h>  // for IN_ADDR
    #else
        #include <winsock2.h> // for windows server 2003/xp
        #include <ws2tcpip.h>
    #endif
#else
    #include <arpa/inet.h>  // for linux
#endif

namespace zpsoe {

namespace zalgorithm {

namespace zip {
#ifdef PLATFORM_WIN32
#if _WIN32_WINNT >= 0x0600  // 0x0600 = Vista
ZPSOE_SHARED_LIB_API bool is_valid_ip_addr(const string &ip) {
    IN_ADDR  sa_;
    return InetPton(AF_INET, ip.c_str(), &sa_) == 1;
}
#else
// https://github.com/wireshark/wireshark/blob/master/wsutil/inet_pton.c
int _inet_pton(const char *src, u_char *dst) {
    #define NS_INADDRSZ	4
    static const char digits[] = "0123456789";
    int saw_digit, octets, ch;
    u_char tmp[NS_INADDRSZ], *tp;

    saw_digit = 0;
    octets = 0;
    *(tp = tmp) = 0;
    while ((ch = *src++) != '\0') {
        const char *pch;

        if ((pch = strchr(digits, ch)) != NULL) {
            size_t new_ = *tp * 10 + (pch - digits);

            if (new_ > 255)
                return (0);
            *tp = (u_char) new_;
            if (! saw_digit) {
                if (++octets > 4)
                    return (0);
                saw_digit = 1;
            }
        } else if (ch == '.' && saw_digit) {
            if (octets == 4)
                return (0);
            *++tp = 0;
            saw_digit = 0;
        } else
            return (0);
    }
    if (octets < 4)
        return (0);
    memcpy(dst, tmp, NS_INADDRSZ);
    return (1);
}

ZPSOE_SHARED_LIB_API bool is_valid_ip_addr(const string &ip) {
    u_char dst_[50];
    return _inet_pton(ip.c_str(), dst_) == 1;
}
#endif
#else
ZPSOE_SHARED_LIB_API bool is_valid_ip_addr(const string &ip) {
    struct sockaddr_in sa_;
    return inet_pton(AF_INET, ip.c_str(), &(sa_.sin_addr)) == 1;
}
#endif

} /* namespace zip */

} /* namespace zalgorithm */

} /* namespace zpsoe */

